import {
    getUserVOByIdUsingPOST,
    updateSecretKeyUsingPOST,
    updateUserUsingPOST,
    userLoginUsingPOST,
} from '@/services/api-hub-be/userController';
import {useModel} from '@@/exports';
import {
    CommentOutlined,
    FieldTimeOutlined,
    LoadingOutlined,
    LockOutlined,
    PlusOutlined,
    UnlockOutlined,
    UserOutlined,
    VerifiedOutlined,
} from '@ant-design/icons';
import {PageContainer, ProForm, ProFormInstance, ProFormText} from '@ant-design/pro-components';
import {Button, Card, Col, Divider, message, Modal, Row, Typography, Upload, UploadFile, UploadProps,} from 'antd';
import {RcFile, UploadChangeParam} from 'antd/es/upload';
import React, {useEffect, useRef, useState} from 'react';
import {uploadFileUsingPOST} from "@/services/api-hub-be/fileController";
import axios from "axios";
import SparkMD5 from 'spark-md5';

const {Paragraph} = Typography;

const avatarStyle: React.CSSProperties = {
    width: '100%',
    textAlign: 'center',
};
const buttonStyle: React.CSSProperties = {
    marginLeft: '30px',
};

// 上传前校验文件
const beforeUpload = (file: RcFile) => {
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    if (!isJpgOrPng) {
        message.error('仅允许上传 JPG/PNG 格式的文件!');
    }
    const isLt2M = file.size / 1024 / 1024 < 5;
    if (!isLt2M) {
        message.error('文件最大上传大小为 5MB!');
    }
    return isJpgOrPng && isLt2M;
};

const Profile: React.FC = () => {
    const [data, setData] = useState<API.UserVO>({});
    const [visible, setVisible] = useState<boolean>(false);
    const [flag, setFlag] = useState<boolean>(false);
    const [open, setOpen] = useState<boolean>(false);
    const [loading, setLoading] = useState(false);
    const [imageUrl, setImageUrl] = useState<string>();
    const {initialState, setInitialState} = useModel('@@initialState');
    const formRef = useRef<
        ProFormInstance<{
            userPassword: string;
        }>
    >();

    useEffect(() => {
        try {
            getUserInfo(initialState?.loginUser?.id);
        } catch (e: any) {
            console.log(e);
        }
    }, []);

    // 获取用户信息
    const getUserInfo = async (id: any) => {
        return getUserVOByIdUsingPOST({id}).then((res) => {
            if (res.data) {
                setInitialState((s: any) => ({...s, loginUser: res.data}));
                setData(res.data);
                setImageUrl(res.data.userAvatar);
            }
        });
    };

    // 显示秘钥
    const showSecretKey = async () => {
        let userPassword = formRef?.current?.getFieldValue('userPassword');

        // 登录
        const res = await userLoginUsingPOST({
            userAccount: data?.userAccount,
            userPassword: userPassword,
        });
        if (res.code === 2000) {
            setOpen(false);
            setVisible(true);
            formRef?.current?.resetFields();
        }
    };

    // 上传按钮
    const uploadButton = (
        <div>
            {loading ? <LoadingOutlined/> : <PlusOutlined/>}
            <div style={{marginTop: 8}}>Upload</div>
        </div>
    );

    // 更新用户信息
    function uploadUser(userAvatar: string, userName: string) {
        const userUpdateDTO = {
            userAvatar: userAvatar,
            userName: userName,
        }
        axios.post("http://api-hub.xn--torp68ch8h18h1jp.top/api/user/update/my", userUpdateDTO, {
            headers: {
                Authorization: localStorage.getItem('token')
            }
        }).then(response => {
        }).catch(error => {
        });
    }

    // 上传文件
    function uploadFile(options) {
        const {file} = options;
        calculateFileMd5(file, (md5Hash) => {
            // 准备请求体参数
            const formData = new FormData();
            formData.append('chunkNumber', '1');
            formData.append('chunkSize', file.size);
            formData.append('currentChunkSize', file.size);
            formData.append('totalSize', file.size);
            formData.append('filename', file.name);
            formData.append('identifier', md5Hash);
            formData.append('relativePath', file.relativePath);
            formData.append('totalChunks', '1');
            formData.append('file', file);
            // 上传预检
            const config = {
                headers: {
                    Authorization: localStorage.getItem('token')
                },
                params: {
                    identifier: md5Hash
                }
            };
            axios.get('http://api-hub.xn--torp68ch8h18h1jp.top/api/file/upload', config)
                .then(response => {
                    // console.log(response)
                    if (response.data.code == 2000) {
                        const fileChunkVO = response.data.data;
                        if (fileChunkVO.isUploaded === 1) {
                            // 文件已存在
                            const imageUrl = fileChunkVO.fileUrl;
                            uploadUser(imageUrl, '');
                            setImageUrl(imageUrl);
                            return;
                        }
                        // 上传预检成功，并且文件未上传，则开始上传
                        axios.post('http://api-hub.xn--torp68ch8h18h1jp.top/api/file/upload', formData, {
                            headers: {
                                Authorization: localStorage.getItem('token')
                            }
                        }).then(response => {
                            if (response.data.data) {
                                const fileChunkVO = response.data.data;
                                // 文件已存在
                                const imageUrl = fileChunkVO.fileUrl;
                                uploadUser(imageUrl, '');
                                setImageUrl(imageUrl);
                            } else {
                                message.error("文件上传失败")
                            }
                        }).catch(error => {
                            message.error("文件上传失败")
                        });
                    } else {
                        message.error("文件上传失败")
                    }
                }).catch(error => {
                message.error("上传预检失败")
            });
        });
    }

    // 计算文件的md5（这里就没有进行切片了，因为当前项目中并没有上传大文件的场景，所以这里就单纯计算以下md5）
    const calculateFileMd5 = (file, callback) => {
        const fileReader = new FileReader();

        // 监听文件读取完成事件
        fileReader.onload = function (e) {
            const arrayBuffer = e.target.result;
            const spark = new SparkMD5.ArrayBuffer();

            // 使用 SparkMD5 计算 MD5 值
            spark.append(arrayBuffer);
            const md5Hash = spark.end();

            callback(md5Hash);
        };

        // 读取文件内容
        fileReader.readAsArrayBuffer(file);
    };


    // 重置秘钥
    const resetSecretKey = async () => {
        try {
            let userPassword = formRef?.current?.getFieldValue('userPassword');
            // 登录
            const res = await userLoginUsingPOST({
                userAccount: data?.userAccount,
                userPassword: userPassword,
            });
            if (res.code === 2000) {
                const res = await updateSecretKeyUsingPOST({
                    id: data?.id,
                });
                if (res.data) {
                    getUserInfo(data?.id);
                    message.success('重置成功！');
                    setOpen(false);
                }
            }
        } catch (e: any) {
            console.log(e);
        }
    };
    return (
        <PageContainer>
            <Row gutter={24}>
                <Col span={8}>
                    <Card title="个人信息" bordered={false}>
                        <Row>
                            <Col style={avatarStyle}>
                                <Upload
                                    name="file"
                                    listType="picture-circle"
                                    showUploadList={false}
                                    beforeUpload={beforeUpload}
                                    customRequest={uploadFile}
                                    accept="image/*"
                                >
                                    {imageUrl ? (
                                        <img
                                            src={data?.userAvatar}
                                            alt="avatar"
                                            style={{width: '100%', borderRadius: '50%'}}
                                        />
                                    ) : (
                                        uploadButton
                                    )}
                                </Upload>
                            </Col>
                        </Row>
                        <Divider/>
                        <Row>
                            <Col>
                                <UserOutlined/> 用户名称：{data?.userName}
                            </Col>
                        </Row>
                        <Divider/>
                        <Row>
                            <Col>
                                <CommentOutlined/> 用户账号：{data?.userAccount}
                            </Col>
                        </Row>
                        <Divider/>
                        <Row>
                            <Col>
                                <VerifiedOutlined/> 用户角色：{data?.userRole}
                            </Col>
                        </Row>
                        <Divider/>
                        <Row>
                            <Col>
                                <FieldTimeOutlined/> 注册时间：{data?.createTime}
                            </Col>
                        </Row>
                    </Card>
                </Col>
                <Col span={16}>
                    <Card title="秘钥操作" bordered={false}>
                        <Row>
                            <Col>
                                {visible ? (
                                    <Paragraph
                                        copyable={{
                                            text: data?.accessKey,
                                        }}
                                    >
                                        <LockOutlined/> accessKey：{data?.accessKey}
                                    </Paragraph>
                                ) : (
                                    <Paragraph>
                                        <UnlockOutlined/> accessKey：*********
                                    </Paragraph>
                                )}
                            </Col>
                        </Row>
                        <Divider/>
                        <Row>
                            <Col>
                                {visible ? (
                                    <Paragraph
                                        copyable={{
                                            text: data?.secretKey,
                                        }}
                                    >
                                        <UnlockOutlined/> secretKey：{data?.secretKey}
                                    </Paragraph>
                                ) : (
                                    <Paragraph>
                                        <UnlockOutlined/> secretKey：*********
                                    </Paragraph>
                                )}
                            </Col>
                        </Row>
                        <Divider/>
                        <Row>
                            <Col>
                                {!visible ? (
                                    <Button
                                        type="primary"
                                        onClick={() => {
                                            setOpen(true);
                                            setFlag(true);
                                        }}
                                    >
                                        查看秘钥
                                    </Button>
                                ) : (
                                    <Button type="primary" onClick={() => setVisible(false)}>
                                        隐藏秘钥
                                    </Button>
                                )}
                                <Button
                                    style={buttonStyle}
                                    onClick={() => {
                                        setOpen(true);
                                        setFlag(false);
                                    }}
                                    type="primary"
                                    danger
                                >
                                    重置秘钥
                                </Button>
                            </Col>
                        </Row>
                    </Card>
                </Col>
            </Row>
            <Modal
                title="查看秘钥"
                open={open}
                onOk={flag ? showSecretKey : resetSecretKey}
                onCancel={() => setOpen(false)}
            >
                <ProForm<{
                    userPassword: string;
                }>
                    formRef={formRef}
                    formKey="check-user-password-form"
                    autoFocusFirstInput
                    submitter={{
                        resetButtonProps: {
                            style: {
                                display: 'none',
                            },
                        },
                        submitButtonProps: {
                            style: {
                                display: 'none',
                            },
                        },
                    }}
                >
                    <ProFormText.Password name="userPassword" placeholder="请输入用户密码"/>
                </ProForm>
            </Modal>
        </PageContainer>
    );
};

export default Profile;
